﻿using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using PropertyManagment.common.Filter;
using PropertyManagment.common.utils;
using PropertyManagment.config;
using PropertyManagment.config.cache;
using PropertyManagment.entity;
using PropertyManagment.entity.dto;
using PropertyManagment.mapper;
using System;
using System.Collections.Generic;
using System.Linq;

namespace PropertyManagment.service.impl {

    public class SysUserServiceImpl : ServiceImpl<SysUserMapper, SysUser>, SysUserService {

        //private readonly AppDbContext context;
        //private readonly DbSet<SysUser> sysUsers;
        //private readonly DbSet<SysUserRole> sysUserRoles;
        //private readonly DbSet<SysRole> sysRoles;
        //private readonly DbSet<SysRoleMenu> sysRoleMenus;
        public ILogger<SysUserServiceImpl> logger { get; set; }

        public ICacheHelper cache { get; set; }
        public SysUserMapper sysUserMapper { get; set; }
        public SysRoleMapper sysRoleMapper { get; set; }
        public SysMenuMapper sysMenuMapper { get; set; }

        public SysUser getByUsername(string username) {
            SysUser sysUser = sysUserMapper.getAll().Where(u => u.username == username).FirstOrDefault();
            return sysUser;
        }

        public string getUserAuthorityInfo(long userId) {
            logger.LogInformation("正在获取用户权限信息");
            SysUser sysUser = sysUserMapper.getById(userId);
            String authority = "";
            if (cache.IsExist("GrantedAuthority:" + sysUser.username)) {
                logger.LogInformation("从缓存中获取");
                // 优先从缓存获取
                authority = cache.Get<string>("GrantedAuthority:" + sysUser.username);
            } else {
                logger.LogInformation("从数据库中获取");
                // 获取角色编码
                List<SysRole> roles = sysRoleMapper.getByUserId(userId);
                if (roles.Count() > 0) {
                    //过滤状态为禁用的角色
                    string roleCodes = String.Join(",", roles.Where(r=>r.statu!=0).Select(r=> new String("ROLE_" + r.code)).ToList());
                    authority = string.Concat(roleCodes, ",");
                }
                // 获取菜单操作编码
                List<long> menuIds = sysMenuMapper.getMenuIdByUserId(userId);
                //var json = JsonConvert.SerializeObject(menuIds);
                //logger.LogError(json);
                if (menuIds.Count() > 0) {
                    List<SysMenu> menus = sysMenuMapper.selectBatchIds(menuIds).ToList();
                    //过滤状态为禁用的菜单
                    string menuPerms = String.Join(",", menus.Where(m=>m.statu!=0).Select(m=> new String(m.perms)).ToList());
                    authority = string.Concat(authority,menuPerms);
                }
                cache.Set("GrantedAuthority:" + sysUser.username, authority, 60*60);
            }
            logger.LogInformation("用户ID - {} ---拥有的权限：{}", userId, authority);
            return authority;
        }
        // 删除某个用户的权限信息
        public void clearUserAuthorityInfo(string username) {
            cache.Remove("GrantedAuthority:" + username);
        }
        // 删除所有与该角色关联的用户的权限信息
        public void clearUserAuthorityInfoByRoleId(long roleId) {
            List<SysUser> sysUsers = sysUserMapper.getByRoleId(roleId);
            sysUsers.ForEach(s => clearUserAuthorityInfo(s.username));
        }
        // 删除所有与该菜单关联的所有用户的权限信息
        public void clearUserAuthorityInfoByMenuId(long menuId) {
            List<SysUser> sysUsers = sysUserMapper.getByMenuId(menuId);
            sysUsers.ForEach(s => clearUserAuthorityInfo(s.username));
        }

        public SysUserDto loadUserByUsername(string username, string password) {
            logger.LogInformation("验证用户名和密码");
            SysUser sysUser = sysUserMapper.getByUsernameAndPassword(username, password);
            if (sysUser == null) {
                throw new UserLoginException("用户名或者密码不正确!");
            } else if(sysUser.statu == 0){
                throw new UserLoginException("用户被限制登录,请联系管理员!");
            }
            logger.LogInformation("账号:" + sysUser.username);
            logger.LogInformation("密码:" + sysUser.password);
            return new SysUserDto(sysUser.id, sysUser.username, getUserAuthority(sysUser.id));
        }
        public SysUserDto loadUserByUsername(string username) {
            SysUser sysUser = getByUsername(username);
            if (sysUser == null) { 
                return null; 
            }else {
                return new SysUserDto(sysUser.id, sysUser.username, getUserAuthority(sysUser.id));
            }
        }

        /**
        * 获取用户权限信息（角色、菜单权限）
        * @param userId
        * @return
        */
        public List<string> getUserAuthority(long userId) {
            logger.LogInformation("获取用户权限信息");
            // 角色(ROLE_admin)、菜单操作权限 sys:user:list
            string authority = getUserAuthorityInfo(userId);  // ROLE_admin,ROLE_normal,sys:user:list,....
            string[] arr = authority.Split(",");
            return arr.ToList();
        }
    }
}
